/*
 * Copyright (C) 2009 Show SMS open source project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.bydavy.android.showsms.model;

//~--- non-JDK imports --------------------------------------------------------

import android.content.Context;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import android.os.Bundle;

import com.bydavy.android.showsms.R;
import com.bydavy.android.showsms.util.AppLog;
import com.bydavy.android.showsms.util.ContactInfos;

//~--- JDK imports ------------------------------------------------------------

import java.util.HashSet;

//~--- classes ----------------------------------------------------------------

/**
 * Class to describe a contact
 * A Contact have a mName, a phone number, a mPhoto and an mId (Id in the phone contacts)
 * The contact can be in the phone contact or not
 *
 * @version        1.1, 10/03/08
 * @author         Davy L.
 */
public class Contact {
    //~--- static fields ------------------------------------------------------

    public static final String EXTRAS_PERSON_ID           = "EXTRAS_PERSON_ID";
    public static final String EXTRAS_PERSON_DISPLAY_NAME = "EXTRAS_PERSON_DISPLAY_NAME";
    public static final String EXTRAS_PERSON_PHONENUMBER  = "EXTRAS_PERSON_PHONENUMBER";
    public static final String EXTRAS_PERSON_PHOTO        = "EXTRAS_PERSON_PHOTO";

    //~--- fields -------------------------------------------------------------

    private long mId;
    private String mDisplayName;
    private String mPhoneNumber;
    private Bitmap mPhoto;
    private final HashSet<UpdateContactListener> mListeners = new HashSet<UpdateContactListener>();

    //~--- constructors -------------------------------------------------------

    public Contact(String phoneNumber) {
        mPhoneNumber = phoneNumber;
        mId          = 0;
        mDisplayName = "";
        mPhoto       = null;
    }

    public Contact(long id, String displayName, String phoneNumber, Bitmap photo) {
        mId          = id;
        mDisplayName = displayName;
        mPhoneNumber = phoneNumber;
        mPhoto       = photo;
    }

    //~--- get methods --------------------------------------------------------

    public long getId() {
        return mId;
    }

    public String getDisplayName() {
        return mDisplayName;
    }

    public String getPhoneNumber() {
        return mPhoneNumber;
    }

    public boolean hasPhoto() {
        if (mPhoto == null) {
            return false;
        }

        return true;
    }

    public Bitmap getPhoto(Context context) {

        if (mId == 0) {
            AppLog.v("This contact is unknow");

            return BitmapFactory.decodeResource(context.getResources(), R.drawable.no_photo);
        } else {
            if (!hasPhoto()) {
                AppLog.v("This contact is know but don't have mPhoto");

                return BitmapFactory.decodeResource(context.getResources(), R.drawable.no_photo);
            }
        }

        AppLog.v("This contact have a mPhoto");

        return mPhoto;
    }

    public static Contact get(String phoneNumber, final Context context, boolean backgroundProcess) {
        if ((phoneNumber == null) || ("").equals(phoneNumber)) {
            throw new IllegalArgumentException("phoneNumber null or empty");
        }

        final Contact c = new Contact(phoneNumber);

        if (!backgroundProcess) {
            updateContact(c, context);
        } else {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    updateContact(c, context);
                }
            }).start();
        }

        return c;
    }

    //~--- methods ------------------------------------------------------------
    //Update contact information. Must have at least the contact phone number
    protected static void updateContact(Contact c, Context context) {
        String phoneNumber = c.getPhoneNumber();
        long id            = ContactInfos.findId(context, phoneNumber);

        if (id != 0) {
            c.mId          = id;
            c.mDisplayName = ContactInfos.findDisplayName(context, id);
            c.mPhoto       = ContactInfos.findPhoto(context, id);

            for (UpdateContactListener listener : c.mListeners) {
                listener.onUpdateContact(c);
            }
        }
    }

    static public Contact constructFromBundle(Bundle bundle) {
        long id            = bundle.getLong(EXTRAS_PERSON_ID);
        String name        = bundle.getString(EXTRAS_PERSON_DISPLAY_NAME);
        String phoneNumber = bundle.getString(EXTRAS_PERSON_PHONENUMBER);
        Bitmap photo       = bundle.getParcelable(EXTRAS_PERSON_PHOTO);

        return new Contact(id, name, phoneNumber, photo);
    }

    public Bundle toBundle() {
        return toBundle(new Bundle());
    }

    public Bundle toBundle(Bundle b) {
        b.putLong(EXTRAS_PERSON_ID, mId);
        b.putString(EXTRAS_PERSON_DISPLAY_NAME, mDisplayName);
        b.putString(EXTRAS_PERSON_PHONENUMBER, mPhoneNumber);
        b.putParcelable(EXTRAS_PERSON_PHOTO, mPhoto);

        return b;
    }

    @Override
    public String toString() {
        StringBuffer s = new StringBuffer("Display Name : " + mDisplayName);

        s.append(", phone number : " + mPhoneNumber);
        s.append(", id : " + mId);

        return s.toString();
    }

    public void addListener(UpdateContactListener l) {
        mListeners.add(l);
    }

    public void removeListener(UpdateContactListener l) {
        mListeners.remove(l);
    }

    //~--- inner interfaces ---------------------------------------------------

    public interface UpdateContactListener {
        public void onUpdateContact(Contact c);
    }
}
